package com.java.simple.study.jvm.gc.reference;

import java.lang.ref.SoftReference;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * @author zhoujunlin
 * @date 2022年11月08日 11:04
 * @desc
 */
public class SoftReferenceTest {

    @Getter
    @Setter
    @ToString
    @AllArgsConstructor
    public static class User {
        private int id;
        private String name;
    }

    public static void main(String[] args) {
        // 创建对象并建立软引用
        //SoftReference<User> userSoftReference = new SoftReference<>(new User(1, "zhoujl"));
        // 上面的一行代码等价于下面代码
        User user = new User(1, "zhoujl");
        SoftReference<User> userSoftReference = new SoftReference<>(user);
        // 取消强引用  只剩下一个软引用
        user = null;

        // 从软引用中重新获得对象
        System.out.println(userSoftReference.get());
        System.out.println("---目前内存还不紧张---");
        System.gc();
        System.out.println("After GC");
        // 垃圾回收过后再次从软引用中获取对象  由于内存充足不会回收软引用对象
        System.out.println(userSoftReference.get());
        System.out.println("---下面开始内存紧张了---");
        try {
            // 让系统认为内存系统资源紧张  不够
            byte[] b = new byte[1024 * 1024 * 7];
            //byte[] b = new byte[1024 * 7168 - 635 * 1024];
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            // 再次获取对象
            // OOM之前  垃圾回收器会回收软引用的可达对象
            System.out.println(userSoftReference.get());
        }

    }

}
